home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / tlp4v11c / source / demo.c next >
Encoding:
C/C++ Source or Header  |  1994-05-17  |  39.6 KB  |  1,323 lines

  1. /* Copyright (C) 1994 Christian Wagner, Tale Software.
  2.  * All rights reserved.
  3.  */
  4.  
  5. #include <conio.h>        /* keyboard fct. */
  6. #include <ctype.h>        /* char lowercase conversion */
  7. #include <mem.h>        /* for standard fades init */
  8. #include <stdio.h>        /* standard I/O fct. */
  9. #include <stdlib.h>        /* random number fct. */
  10. #include <time.h>        /* for randomize() */
  11.  
  12. #include "tgdlp4.h"        /* TGDLP4 functions */
  13. #include "tgdsupp.h"        /* TGD support fct. */
  14. #include "lp4supp.h"        /* LP4 file support fct. */
  15.  
  16. /* main() error codes (returned to DOS as errorlevels) */
  17. #define DEMOERR_NO 0
  18. #define DEMOERR_BADVGA 1
  19. #define DEMOERR_LOAD 2
  20. #define DEMOERR_NOMEM 3
  21.  
  22. /* getch() key ID's */
  23. #define ENTER_KEY 13
  24. #define ESC_KEY 27
  25. #define SPACE_KEY 32
  26. #define CRSR_UP_KEY 72
  27. #define CRSR_DOWN_KEY 80
  28. #define CRSR_LEFT_KEY 75
  29. #define CRSR_RIGHT_KEY 77
  30.  
  31. /* global variables */
  32. char *filename;
  33. ubyte error=DEMOERR_NO,loaderr;
  34. ubyte allblack[256*3],allwhite[256*3];
  35.  
  36.  
  37. /* universal fade in/out ...and I mean UNIVERSAL */
  38. void fade(ubyte frames,ubyte startcol,ubyte colnum,const ubyte *destcoltab,const ubyte *srccoltab)
  39. { ubyte tempcoltab[256*3];
  40.   uword a,b;
  41.   word coldelta[256*3];
  42.  
  43.   /* instant fade? */
  44.   if (!frames) { waittof(); rgb6(startcol,colnum,destcoltab); return; };
  45.  
  46.   /* calculate RGB color deltas per fade step */
  47.   for (a=0;a<=(uword)colnum*3;a+=3)
  48.   { coldelta[a]=((word)destcoltab[a]-(word)srccoltab[a])*520;
  49.     coldelta[a+1]=((word)destcoltab[a+1]-(word)srccoltab[a+1])*520;
  50.     coldelta[a+2]=((word)destcoltab[a+2]-(word)srccoltab[a+2])*520;
  51.  
  52.     coldelta[a]/=(word)frames;
  53.     coldelta[a+1]/=(word)frames;
  54.     coldelta[a+2]/=(word)frames;
  55.   };
  56.  
  57.   /* fade */
  58.   for (a=1;a<=frames;a+=1)
  59.   { for (b=0;b<=(uword)colnum*3;b+=3)
  60.     { tempcoltab[b]=srccoltab[b]+(byte)((coldelta[b]*(word)a)/520);
  61.       tempcoltab[b+1]=srccoltab[b+1]+(byte)((coldelta[b+1]*(word)a)/520);
  62.       tempcoltab[b+2]=srccoltab[b+2]+(byte)((coldelta[b+2]*(word)a)/520);
  63.     };
  64.     waittof(); rgb6(startcol,colnum,tempcoltab);
  65.   };
  66.  
  67.   /* compensate rounding errors */
  68.   waittof(); rgb6(startcol,colnum,destcoltab);
  69. }
  70.  
  71. /* graphic primitives part: clear presentation box and
  72.  * print new description.
  73.  */
  74. void primclear(char *description)
  75. {
  76.   /* redraw presentation box */
  77.   pen(PEN_F,0); rectangle(30,210,289,359);
  78.  
  79.   /* clear text */
  80.   pfill(TRUE);
  81.   rectangle(0,370,319,399);
  82.   pfill(FALSE);
  83.  
  84.   /* print new description */
  85.   bltmode(BM_COLREPLACE|BM_TRANSPARENT); pen(PEN_F,24);
  86.   drawmode(DM_OR);
  87.   prttext("\x0c");
  88.   prttext(description);
  89.   drawmode(DM_SOLID); bltmode(BM_SOLID);
  90. }
  91.  
  92. ubyte primdemo(bcdescr huge *introbc)
  93. { ubyte primcolors[256*3]={ 0,0,0, 16,0,32, 0,0,0, 12,0,24 };
  94.   ubyte darkvio[256*3];
  95.   ubyte starspeed[45];
  96.   word starx[45],stary[45],oldstarx[45],oldstary[45];
  97.   word hexagon[]={ 0,370, 10,390, 10,410, 0,430, -10,410, -10,390 };
  98.   word a,b,triangles[6];
  99.   bcdescr huge *primbc=0,huge *prim1bc=0;
  100.   fcdescr huge *primfc=0;
  101.   sincostab far *primsincos;
  102.  
  103.   /* init fade colormap (fade color = hexagon color) */
  104.   for (a=0;a<=765;a+=3)
  105.   { darkvio[a]=16; darkvio[a+1]=0; darkvio[a+2]=32; };
  106.  
  107.   /* draw the hexagons */
  108.   pen(PEN_F,6);
  109.   for (a=0;a<10;a+=1)
  110.   { for (b=0;b<15;b+=1)
  111.     { waittof();
  112.       drawpoly(6,hexagon);
  113.       if (a&1) { hexagon[0]-=23; hexagon[2]-=23; hexagon[4]-=23;
  114.          hexagon[6]-=23; hexagon[8]-=23; hexagon[10]-=23;
  115.            }
  116.       else { hexagon[0]+=23; hexagon[2]+=23; hexagon[4]+=23;
  117.          hexagon[6]+=23; hexagon[8]+=23; hexagon[10]+=23;
  118.        };
  119.     };
  120.  
  121.     if (a&1) { hexagon[0]+=12; hexagon[2]+=12; hexagon[4]+=12;
  122.            hexagon[6]+=12; hexagon[8]+=12; hexagon[10]+=12;
  123.          }
  124.     else { hexagon[0]-=12; hexagon[2]-=12; hexagon[4]-=12;
  125.        hexagon[6]-=12; hexagon[8]-=12; hexagon[10]-=12;
  126.      };
  127.  
  128.     hexagon[1]+=44; hexagon[3]+=44; hexagon[5]+=44;
  129.     hexagon[7]+=44; hexagon[9]+=44; hexagon[11]+=44;
  130.   };
  131.  
  132.   /* fade into hexagon color */
  133.   fade(140,0,255,darkvio,introbc->cmap);
  134.   /* free tale background bitmap (we only needed the color information) */
  135.   freebc(introbc);
  136.  
  137.  
  138.   /* load background pattern */
  139.   filename="lp4demo\\basketgr.lp4";
  140.   primbc=readbc(filename,1,&loaderr);
  141.   if (!primbc) { error=DEMOERR_LOAD; goto primcleanup; };
  142.  
  143.   /* load pixelz bitmap */
  144.   filename="lp4demo\\pixelz.lp4";
  145.   prim1bc=readbc(filename,1,&loaderr);
  146.   if (!prim1bc) { error=DEMOERR_LOAD; goto primcleanup; };
  147.  
  148.   /* load galafont */
  149.   filename="lp4demo\\galafnt.lp4";
  150.   primfc=readfc(filename,1,&loaderr);
  151.   if (!primfc) { error=DEMOERR_LOAD; goto primcleanup; };
  152.   /* set galafont as active font */
  153.   font(primfc->tgdfmdescr);
  154.  
  155.   /* set 320x200 phys. resolution, viewmode 0 */
  156.   waittof(); screenmode(SM_320x200);
  157.  
  158.   /* patternize background */
  159.   bltbitmap(0,0,0,0,primbc->tgdbmdescr->xsize,primbc->tgdbmdescr->ysize,primbc->tgdbmdescr);
  160.   pattern(0,0,primbc->tgdbmdescr->xsize+1,primbc->tgdbmdescr->ysize+1);
  161.   pfill(TRUE);
  162.   rectangle(0,200,319,399);
  163.   pfill(FALSE);
  164.  
  165.   /* free pattern */
  166.   freebc(primbc); primbc=0;
  167.  
  168.   /* draw shadow of presentation box */
  169.   drawmode(DM_OR); pen(PEN_F,2);
  170.   rectangle(40,220,299,369);
  171.   drawmode(DM_SOLID);
  172.   /* draw presentation box */
  173.   pen(PEN_F,0); rectangle(30,210,289,359);
  174.  
  175.   /* blit pixelz bitmap into presentation box */
  176.   bltmode(BM_COLREPLACE);
  177.   bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,255);
  178.   bltbitmap(100,265,0,0,prim1bc->tgdbmdescr->xsize,prim1bc->tgdbmdescr->ysize,prim1bc->tgdbmdescr);
  179.   bltmode(BM_SOLID);
  180.   /* free pixelz bm. - we don't need it anymore */
  181.   freebc(prim1bc); prim1bc=0;
  182.  
  183.   /* pixelz stencil fill --- THIS IS FOR YOU DIRK */
  184.   for (b=3,a=12;a<60;a+=3,b+=4)
  185.   { primcolors[a]=b; primcolors[a+1]=0; primcolors[a+2]=(b>>1)+(b>>2); };
  186.   drawmode(DM_AND);
  187.   for (b=0,a=265;a<=305;a+=1,b=(b+1)&15)
  188.   { pen(PEN_F,b+4); line(100,a,211,a); };
  189.   drawmode(DM_SOLID);
  190.  
  191.   /* prepare star colors */
  192.   for (b=32,a=60;a<72;a+=3,b+=8)
  193.   { primcolors[a]=b; primcolors[a+1]=b; primcolors[a+2]=b; };
  194.  
  195.   /* generate random starfield */
  196.   for (a=0;a<45;a+=1)
  197.   { starspeed[a]=(rand()&3)+1;
  198.     starx[a]=(rand()%260)+30;
  199.     stary[a]=(rand()%150)+210;
  200.     oldstary[a]=0;
  201.   };
  202.  
  203.   /* font colors */
  204.   primcolors[72]=0; primcolors[73]=32; primcolors[74]=48;
  205.   primcolors[75]=0; primcolors[76]=40; primcolors[77]=56;
  206.  
  207.   /* display some text */
  208.   bltmode(BM_COLREPLACE|BM_TRANSPARENT);
  209.   bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,24);
  210.   drawmode(DM_OR);
  211.   txtcrsr(0,370);
  212.   prttext("Welcome to the graphics\r\nprimitives section.        <key>");
  213.   drawmode(DM_SOLID); bltmode(BM_SOLID);
  214.  
  215.   /* show what was prepared */
  216.   fade(140,0,25,primcolors,darkvio);
  217.  
  218.   while (!kbhit())
  219.   { /* clear old star positions */
  220.     for (a=0;a<45;a+=1)
  221.     { if (oldstary[a]) { pen(PEN_F,0); writepixel(oldstarx[a],oldstary[a]); };
  222.     };
  223.  
  224.     /* set new star positions and calc next star positions */
  225.     for (a=0;a<45;a+=1)
  226.     { if (!readpixel(starx[a],stary[a])) { pen(PEN_F,starspeed[a]+19); writepixel(starx[a],stary[a]);
  227.                        oldstarx[a]=starx[a]; oldstary[a]=stary[a]; }
  228.       else oldstary[a]=0;
  229.  
  230.       starx[a]-=starspeed[a];
  231.       if (starx[a]<30) starx[a]+=289-29;
  232.     };
  233.  
  234.     /* display star positions for one frame */
  235.     waittof();
  236.   };
  237.  
  238.   if (!getch()) getch();
  239.  
  240.  
  241.   /* print line description */
  242.   primclear("Lines (no floating point used)\r\nPress a key.");
  243.  
  244.   /* prepare line colors */
  245.   for (b=34,a=12;a<36;a+=3,b+=4)
  246.   { primcolors[a]=0; primcolors[a+1]=b; primcolors[a+2]=0; };
  247.   for (b=34,a=36;a<60;a+=3,b+=4)
  248.   { primcolors[a]=b; primcolors[a+1]=0; primcolors[a+2]=0; };
  249.   for (a=60;a<69;a+=3)
  250.   { primcolors[a]=0; primcolors[a+1]=0; primcolors[a+2]=0; };
  251.   primcolors[69]=0; primcolors[70]=47; primcolors[71]=63;
  252.   waittof(); rgb6(4,19,primcolors+12);
  253.  
  254.   /* lines */
  255.   for (a=0;a<18;a+=1)
  256.   { waittof();
  257.     pen(PEN_F,(a&7)+4); line(30,215+(a<<3),38+(a<<3),359);
  258.   };
  259.  
  260.   for (a=0;a<18;a+=1)
  261.   { waittof();
  262.     pen(PEN_F,(a&7)+12); line(145+(a<<3),210,289,218+(a<<3));
  263.   };
  264.  
  265.   for (b=0,a=0;a<4000;a+=50,b=(b+1)&3)
  266.   { primsincos=tgdsincos(a);
  267.     waittof();
  268.     pen(PEN_F,b+20); line((primsincos->cos)/750+160,(primsincos->sin)/1000+285,(primsincos->cos)/2000+160,(primsincos->sin)/2000+285);
  269.   };
  270.  
  271.   /* color cycling */
  272.   a=1;
  273.   while (!kbhit())
  274.   { framewait(4);
  275.     rgb6(20+a,3-a,primcolors+60);
  276.     if (a) rgb6(20,a-1,primcolors+60+(4-a)*3);
  277.     a=(a+1)&3;
  278.   };
  279.  
  280.   if (!getch()) getch();
  281.  
  282.  
  283.   /* print arc description */
  284.   primclear("Arcs. Sorry - no animation here.\r\nPress a key.");
  285.  
  286.   /* yellows */
  287.   for (a=0;a<4;a+=1)
  288.   { primcolors[12+a*3]=63-(a<<3); primcolors[13+a*3]=63-(a<<3); primcolors[14+a*3]=0; };
  289.   waittof(); rgb6(4,3,primcolors+12);
  290.  
  291.   /* arcs */
  292.   pen(PEN_F,4);
  293.   arc(160,285,58,58,0,4000);
  294.  
  295.   for (a=0,b=0;a<4000;a+=500,b=(b+1)&3)
  296.   { primsincos=tgdsincos(a);
  297.     pen(PEN_F,b+4);
  298.     arc(160+(primsincos->cos/565),285-(primsincos->sin/565),12,12,a-1000,a+1000);
  299.   };
  300.  
  301.   for (a=0,b=0;a<4000;a+=500,b=(b+1)&3)
  302.   { primsincos=tgdsincos(a);
  303.     pen(PEN_F,b+4);
  304.     arc(160+(primsincos->cos/819),285-(primsincos->sin/819),40,40,a+2000,a+3000);
  305.   };
  306.  
  307.   if (!getch()) getch();
  308.  
  309.  
  310.   /* print rectangle description */
  311.   primclear("Area Functions:\r\nRectangles...              <key>");
  312.  
  313.   /* set rectangle random colors */
  314.   for (a=12;a<72;a+=3)
  315.   { primcolors[a]=(rand()&15)+16;
  316.     primcolors[a+1]=(rand()&15)+16;
  317.     primcolors[a+2]=(rand()&31)+32;
  318.   };
  319.   waittof(); rgb6(4,19,primcolors+12);
  320.  
  321.   /* draw rectangles */
  322.   while (!kbhit())
  323.   { for (a=0;a<100;a+=1)
  324.     { pen(PEN_F,rand()%20+4);
  325.       rectangle(rand()%260+30,rand()%150+210,rand()%260+30,rand()%150+210);
  326.     };
  327.   };
  328.  
  329.   if (!getch()) getch();
  330.  
  331.  
  332.   /* print ellipse description */
  333.   primclear("Area Functions:\r\n\Ellipses...                <key>");
  334.  
  335.   /* set ellipse random colors */
  336.   for (a=12;a<72;a+=3)
  337.   { primcolors[a]=(rand()&31)+32;
  338.     primcolors[a+1]=(rand()&15)+16;
  339.     primcolors[a+2]=(rand()&15)+16;
  340.   };
  341.   waittof(); rgb6(4,19,primcolors+12);
  342.  
  343.   /* draw ellipses */
  344.   drawreg(30,210,259,149);
  345.   while (!kbhit())
  346.   { for (a=0;a<100;a+=1)
  347.     { pen(PEN_F,rand()%20+4);
  348.       ellipse(rand()%320,rand()%200+200,rand()%60,rand()%60);
  349.     };
  350.   };
  351.  
  352.   if (!getch()) getch();
  353.  
  354.  
  355.   /* reset clip region */
  356.   drawreg(0,200,319,199);
  357.   /* print polygon description */
  358.   primclear("Area Functions:\r\n\Convex Polygons.          <key>");
  359.  
  360.   /* set triangle random colors */
  361.   for (a=12;a<72;a+=3)
  362.   { primcolors[a]=(rand()&15)+16;
  363.     primcolors[a+1]=(rand()&31)+32;
  364.     primcolors[a+2]=(rand()&15)+16;
  365.   };
  366.   waittof(); rgb6(4,19,primcolors+12);
  367.  
  368.   /* draw triangles */
  369.   drawreg(30,210,259,149);
  370.   while (!kbhit())
  371.   { for (a=0;a<100;a+=1)
  372.     { pen(PEN_F,rand()%20+4);
  373.       triangles[0]=rand()%320; triangles[1]=rand()%200+200;
  374.       triangles[2]=rand()%320; triangles[3]=rand()%200+200;
  375.       triangles[4]=rand()%320; triangles[5]=rand()%200+200;
  376.       drawpoly(3,triangles);
  377.     };
  378.   };
  379.  
  380.   if (!getch()) getch();
  381.  
  382.  
  383.   /* fade into white */
  384.   fade(210,0,25,allwhite,primcolors);
  385.  
  386.   /* free used font */
  387.   font(0); freefc(primfc); primfc=0;
  388.  
  389. primcleanup:
  390.   if (error) { /* free everything if something went wrong */
  391.            if (primbc) freebc(primbc);
  392.            if (prim1bc) freebc(prim1bc);
  393.            if (primfc) freefc(primfc);
  394.          };
  395.   return(error);
  396. }
  397.  
  398. ubyte bitmapdemo(void)
  399. { int pressedkey;
  400.   ubyte allred[256*3];
  401.   uword srcx,srcy;
  402.   word a,b,x,y,ax,ay;
  403.   word talegon[]={ 110,230, 140,230, 120,274, 90,274 };
  404.   bcdescr huge *bitmapbc=0,huge *bitmap1bc=0;
  405.  
  406.   /* clear menu screen */
  407.   pen(PEN_F,0);
  408.   for (a=0;a<320;a+=2)
  409.   { waittof();
  410.     line(160,600,a,400);
  411.     line(160,600,a+1,400);
  412.   };
  413.   for (a=400;a<799;a+=3)
  414.   { waittof();
  415.     line(160,600,319,a);
  416.     line(160,600,319,a+1);
  417.     line(160,600,319,a+2);
  418.   };
  419.   for (a=319;a>=0;a-=2)
  420.   { waittof();
  421.     line(160,600,a,799);
  422.     line(160,600,a-1,799);
  423.   };
  424.   for (a=799;a>400;a-=3)
  425.   { waittof();
  426.     line(160,600,0,a);
  427.     line(160,600,0,a-1);
  428.     line(160,600,0,a-2);
  429.   };
  430.  
  431.  
  432.   /* load violet background pattern */
  433.   filename="lp4demo\\bitmpat.lp4";
  434.   bitmapbc=readbc(filename,1,&loaderr);
  435.   if (!bitmapbc) { error=DEMOERR_LOAD; goto bitmapcleanup; };
  436.  
  437.   /* hide screen build up */
  438.   waittof(); rgb6(0,255,allblack);
  439.   /* give me 320x200 phys. res. and 640x400 virt. res. */
  440.   waittof(); screenmode(SM_320x200); viewmode(VM_640x400);
  441.  
  442.   /* do a little pattern fill with the violet pattern */
  443.   bltbitmap(320,0,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  444.   pattern(320,0,bitmapbc->tgdbmdescr->xsize+1,bitmapbc->tgdbmdescr->ysize+1);
  445.   pfill(TRUE);
  446.   rectangle(0,0,319,399);
  447.   pfill(FALSE);
  448.  
  449.   /* create shadowed box */
  450.   drawmode(DM_OR);
  451.   pen(PEN_F,16); rectangle(40,210,280,294);
  452.   drawmode(DM_SOLID);
  453.  
  454.   /* create red green blue random swirl for tale logo */
  455.   for (a=0;a<3;a+=1)
  456.   { for (x=480;x<512;x+=1)
  457.     { for (y=0;y<32;y+=1)
  458.       { pen(PEN_F,32+(a<<2)+(rand()&3));
  459.     writepixel((a<<5)+x,y);
  460.       };
  461.     };
  462.   };
  463.   /* draw tale logo and fill it with the created random swirl */
  464.   for (a=0;a<3;a+=1)
  465.   { pattern(480+(a<<5),0,32,32);
  466.     pfill(TRUE);
  467.     drawpoly(4,talegon);
  468.     talegon[0]+=40; talegon[2]+=40; talegon[4]+=40; talegon[6]+=40;
  469.   };
  470.   pfill(FALSE);
  471.  
  472.   /* display lower part of virt. screen */
  473.   viewreg(0,200);
  474.   waittof(); rgb6(0,bitmapbc->cmdescr->colors,bitmapbc->cmap);
  475.  
  476.   /* build text in invisible upper part of virt. screen */
  477.   bltmode(BM_TRANSPARENT); bltpen(PEN_B,0);
  478.   txtcrsr(0,0);
  479.   prttext("Let's take a look at the bitmap\r\n");
  480.   prttext("functions offered by the TGDLP4\r\n");
  481.   prttext("Graphics Driver...\r\n\n");
  482.   prttext("Perhaps the most important feature about\r\n");
  483.   prttext("bitmaps in this module is that there are\r\n");
  484.   prttext("no size restrictions: A bitmap can be as\r\n");
  485.   prttext("small as 1x1 or as big as 10000x10000\r\n");
  486.   prttext("pixels. The only limitation is the\r\n");
  487.   prttext("available base memory.\r\n");
  488.   prttext("Press a key to blit a 640x388 bitmap\r\n");
  489.   prttext("into VRAM.\r\n");
  490.   bltmode(BM_SOLID);
  491.  
  492.   framewait(35);
  493.  
  494.   /* another nice effect... only scroll up info text */
  495.   for (a=200;a>=104;a-=1)
  496.   { framewait(2); splitscrn(a); };
  497.  
  498.   /* while the user is reading some text, load the next bitmap */
  499.   filename="lp4demo\\pheonix.lp4";
  500.   bitmap1bc=readbc(filename,1,&loaderr);
  501.   if (!bitmap1bc) { error=DEMOERR_LOAD; goto bitmapcleanup; };
  502.  
  503.   /* wait for a key */
  504.   if (!getch()) getch();
  505.  
  506.   /* scroll text away */
  507.   for (a=104;a<=200;a+=1)
  508.   { framewait(2); splitscrn(a); };
  509.  
  510.   /* hide display */
  511.   fade(210,0,bitmapbc->cmdescr->colors,allblack,bitmapbc->cmap);
  512.  
  513.   /* free pattern bitmap */
  514.   freebc(bitmapbc); bitmapbc=0;
  515.  
  516.  
  517.   /* blit next bitmap into VRAM */
  518.   bltbitmap(0,8,0,0,639,387,bitmap1bc->tgdbmdescr);
  519.  
  520.   /* the bitmap is sorted by luminance... take brightest color
  521.    * as text color.
  522.    */
  523.   bltmode(BM_COLREPLACE); bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,bitmap1bc->cmdescr->colors);
  524.   txtcrsr(0,0); prttext("Cursor Keys = scroll around; ESC = Exit ");
  525.   bltmode(BM_SOLID);
  526.  
  527.   /* show what we've done */
  528.   splitscrn(192); viewreg(0,8);
  529.   waittof(); rgb6(0,bitmap1bc->cmdescr->colors,bitmap1bc->cmap);
  530.  
  531.   /* let the user scroll around a bit */
  532.   x=0; y=8; ax=0; ay=0; //syncxscroll(FALSE);
  533.   while ((pressedkey=getch())!=ESC_KEY)
  534.   { if (!pressedkey) { switch (getch())
  535.                { case CRSR_UP_KEY: ay-=1; break;
  536.              case CRSR_DOWN_KEY: ay+=1; break;
  537.              case CRSR_LEFT_KEY: ax-=1; break;
  538.              case CRSR_RIGHT_KEY: ax+=1; break;
  539.              default: ax=0; ay=0;
  540.                }
  541.              }
  542.     else { ax=0; ay=0; };
  543.  
  544.     while (!kbhit())
  545.     { x+=ax; y+=ay;
  546.       if (y<8) { y=8; ay=0; }
  547.       else if (y>204) { y=204; ay=0; };
  548.  
  549.       if (x<0) { x=0; ax=0; }
  550.       else if (x>320) { x=320; ax=0; };
  551.  
  552.       //waittof();
  553.       viewreg(x,y);
  554.     };
  555.   };
  556.   //syncxscroll(TRUE);
  557.  
  558.   fade(140,0,bitmap1bc->cmdescr->colors,allblack,bitmap1bc->cmap);
  559.   /* remove info line */
  560.   splitscrn(256);
  561.  
  562.   viewmode(VM_320x200); drawreg(0,200,319,199); clearreg();
  563.  
  564.   bltmode(BM_COLREPLACE);
  565.   txtcrsr(0,312);
  566.   prttext("When dealing with a huge bitmap it is\r\n");
  567.   prttext("often usefull to be able to extract a\r\n");
  568.   prttext("rectangular area of that bitmap.\r\n\n");
  569.   prttext("TGDLP4 supports this key operation (as\r\n");
  570.   prttext("you can see). You can blit rectangular\r\n");
  571.   prttext("parts which may be located anywhere in\r\n");
  572.   prttext("a larger bitmap and have any size to\r\n");
  573.   prttext("anywhere on the screen.\r\n\n");
  574.   prttext("Press a key to continue.");
  575.   bltmode(BM_SOLID);
  576.  
  577.   /* show display again */
  578.   fade(140,0,bitmap1bc->cmdescr->colors,bitmap1bc->cmap,allblack);
  579.  
  580.   /* limit region where blitting is possible */
  581.   drawreg(0,200,319,111);
  582.   /* blit bitmap extracts */
  583.   while (!kbhit())
  584.   { /* get source position of blit */
  585.     srcx=rand()%640; srcy=rand()%388;
  586.     /* get size of blit */
  587.     x=rand()%(640-srcx); y=rand()%(388-srcy);
  588.  
  589.     /* slow the whole thing down a little bit so it doesn't go crazy
  590.      * on my VL board. You may want to remove waittof() for a slow
  591.      * '286 PC.
  592.      */
  593.     waittof();
  594.     /* do the blit */
  595.     bltbitmap(rand()%320,(rand()%112)+200,srcx,srcy,x,y,bitmap1bc->tgdbmdescr);
  596.   };
  597.   /* enable access to all parts of the screen again */
  598.   drawreg(0,200,319,199);
  599.  
  600.   /* get key */
  601.   if (!getch()) getch();
  602.  
  603.   /* prepare redness fade */
  604.   for (a=0;a<=765;a+=3)
  605.   { allred[a]=33; allred[a+1]=0; allred[a+2]=0; };
  606.   /* go red */
  607.   fade(210,0,255,allred,bitmap1bc->cmap);
  608.  
  609.   /* free heroes bitmap */
  610.   freebc(bitmap1bc); bitmap1bc=0;
  611.  
  612.  
  613.   /* load crunchy */
  614.   filename="lp4demo\\crunchy.lp4";
  615.   bitmapbc=readbc(filename,1,&loaderr);
  616.   if (!bitmapbc) { error=DEMOERR_LOAD; goto bitmapcleanup; };
  617.  
  618.   /* draw red horizontal lines */
  619.   for (a=200;a<400;a+=1)
  620.   { b=a&7;
  621.     if (b<4) { pen(PEN_F,b+1); }
  622.     else pen(PEN_F,8-b);
  623.     line(0,a,319,a);
  624.   };
  625.  
  626.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,5);
  627.   txtcrsr(0,200);
  628.   prttext("Apart from doing 'raw' blits this\r\n");
  629.   prttext("Graphics Driver supports block image\r\n");
  630.   prttext("transfer modifiers... Here are some\r\n");
  631.   prttext("examples:");
  632.   bltmode(BM_SOLID);
  633.  
  634.   /* draw original image */
  635.   bltbitmap(10,240,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  636.  
  637.   /* draw background transparent image */
  638.   bltmode(BM_TRANSPARENT); bltpen(PEN_B,6);
  639.   bltbitmap(110,240,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  640.   /* draw foreground transparent image */
  641.   bltpen(PEN_B,8);
  642.   bltbitmap(210,240,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  643.  
  644.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); bltpen(PEN_B,0); pen(PEN_F,5);
  645.   txtcrsr(10,280);
  646.   prttext("selectable transparent color");
  647.   bltmode(BM_SOLID);
  648.  
  649.   /* draw original image */
  650.   bltbitmap(10,295,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  651.  
  652.   /* draw background transparent, foreground color-replaced */
  653.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); bltpen(PEN_B,6); bltpen(PEN_F,8); pen(PEN_B,6); pen(PEN_F,13);
  654.   bltbitmap(90,295,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  655.   /* draw foreground transparent, background color-replaced */
  656.   bltpen(PEN_B,8); bltpen(PEN_F,6); pen(PEN_B,8); pen(PEN_F,14);
  657.   bltbitmap(170,295,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  658.   /* draw everything color-replaced */
  659.   bltmode(BM_COLREPLACE); bltpen(PEN_B,6); bltpen(PEN_F,8); pen(PEN_B,15); pen(PEN_F,16);
  660.   bltbitmap(250,295,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  661.  
  662.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,5);
  663.   txtcrsr(10,335);
  664.   prttext("on the fly color replacement");
  665.   bltmode(BM_SOLID);
  666.  
  667.   /* draw original image */
  668.   bltbitmap(10,350,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  669.  
  670.   /* shadow fun */
  671.   bltmode(BM_TRANSPARENT); bltpen(PEN_B,6); drawmode(DM_OR);
  672.   bltbitmap(110,350,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  673.   bltbitmap(130,350,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  674.   drawmode(DM_XOR);
  675.   bltbitmap(210,350,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  676.   bltbitmap(225,350,0,0,bitmapbc->tgdbmdescr->xsize,bitmapbc->tgdbmdescr->ysize,bitmapbc->tgdbmdescr);
  677.  
  678.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); bltpen(PEN_B,0); pen(PEN_B,0); pen(PEN_F,8);
  679.   txtcrsr(10,390);
  680.   prttext("fun with shadows...press a key");
  681.   drawmode(DM_SOLID); bltmode(BM_SOLID);
  682.  
  683.   /* show display again */
  684.   fade(140,0,bitmapbc->cmdescr->colors,bitmapbc->cmap,allred);
  685.  
  686.   /* get key */
  687.   if (!getch()) getch();
  688.  
  689.   /* end of bitmap part... clean up */
  690.   fade(140,0,bitmapbc->cmdescr->colors,allwhite,bitmapbc->cmap);
  691.  
  692.   /* free crunchy bitmap */
  693.   freebc(bitmapbc); bitmapbc=0;
  694.  
  695. bitmapcleanup:
  696.   if (error) { /* just in case splitscrn is still active */
  697.            splitscrn(256);
  698.  
  699.            /* free used bitmaps */
  700.            if (bitmapbc) freebc(bitmapbc);
  701.            if (bitmap1bc) freebc(bitmap1bc);
  702.          };
  703.   return(error);
  704. }
  705.  
  706. ubyte fontdemo(fcdescr huge *introfc)
  707. { char *formtext;
  708.   ubyte const introfntcol[]={ 56,48,56 };
  709.   ubyte const patt2col[]={  0,0,0,  10,0,0,  20,0,0,  30,0,0,  63,63,63,  63,63,0,  0,0,63,  36,63,0,  0,0,0,  63,20,20,  63,30,30,  63,40,40,  0,0,0,  63,0,63,  63,40,63,  63,50,63 };
  710.   byte crsrrightkey=FALSE;
  711.   uword textsize;
  712.   word a;
  713.   word triangle1[]={ 0,200, 160,200, 0,300 };
  714.   word triangle2[]={ 0,300, 0,399, 160,399 };
  715.   word triangle3[]={ 319,300, 319,399, 160,399 };
  716.   word triangle4[]={ 160,200, 319,200, 319,300 };
  717.   bcdescr huge *fontbc=0,huge *font1bc=0;
  718.   fcdescr huge *fontfc=0,huge *font1fc=0, huge *font2fc=0;
  719.  
  720.   /* clear invisible upper part of virtual screen */
  721.   pen(PEN_F,0); rectangle(0,0,319,399);
  722.  
  723.   /* reprint menu text (will be used as pattern) */
  724.   txtcrsr(0,0);
  725.   prttext("Use cursor keys to select:");
  726.   txtcrsr(50,96);
  727.   prttext("Graphic Primitives\r\nBitmaps\r\nFonts & Text\r\nQuit");
  728.  
  729.   /* set pattern */
  730.   pattern(0,0,320,400);
  731.   pfill(TRUE);
  732.   /* pattern-in text (and pattern-out the background) */
  733.   for (a=0;a<160;a+=1)
  734.   { waittof();
  735.     line(a,a+400,319-a,a+400);
  736.     line(319-a,a+400,319-a,799-a);
  737.     line(a,799-a,319-a,799-a);
  738.     line(a,a+400,a,799-a);
  739.   };
  740.   pfill(FALSE);
  741.  
  742.   fade(140,1,0,allblack,introfntcol);
  743.  
  744.  
  745.   /* load background pattern (strips) */
  746.   filename="lp4demo\\strips.lp4";
  747.   fontbc=readbc(filename,1,&loaderr);
  748.   if (!fontbc) { error=DEMOERR_LOAD; goto fontcleanup; };
  749.  
  750.   /* set ALL colors to black */
  751.   waittof(); rgb6(0,255,allblack);
  752.  
  753.   /* select page mode */
  754.   viewmode(VM_320x400);
  755.  
  756.   /* draw background pattern (strips) */
  757.   bltbitmap(0,0,0,0,fontbc->tgdbmdescr->xsize,fontbc->tgdbmdescr->ysize,fontbc->tgdbmdescr);
  758.   pattern(0,0,fontbc->tgdbmdescr->xsize+1,fontbc->tgdbmdescr->ysize+1);
  759.   pfill(TRUE);
  760.   rectangle(0,0,319,399);
  761.   pfill(FALSE);
  762.  
  763.   /* print introduction */
  764.   bltmode(BM_TRANSPARENT); bltpen(PEN_B,0);
  765.   txtcrsr(0,0);
  766.   prttext("And you thought the menu\r\n");
  767.   prttext("font is not a real font...");
  768.   txtcrsr(0,160);
  769.   prttext("By the way, creating this\r\n");
  770.   prttext("font didn't take ages. In\r\n");
  771.   prttext("fact, it was done in five\r\n");
  772.   prttext("minutes. Press a key.");
  773.   bltmode(BM_SOLID);
  774.  
  775.   /* show page 0 (the page we have prepared) */
  776.   fade(140,0,fontbc->cmdescr->colors,fontbc->cmap,allblack);
  777.  
  778.   /* prepare page 1 */
  779.   drawpage(1);
  780.  
  781.   /* draw background pattern (again) - but this time on page 1 */
  782.   bltbitmap(0,0,0,0,fontbc->tgdbmdescr->xsize,fontbc->tgdbmdescr->ysize,fontbc->tgdbmdescr);
  783.   pattern(0,0,fontbc->tgdbmdescr->xsize+1,fontbc->tgdbmdescr->ysize+1);
  784.   pfill(TRUE);
  785.   rectangle(0,0,319,399);
  786.   pfill(FALSE);
  787.  
  788.   bltmode(BM_TRANSPARENT);
  789.   txtcrsr(0,0);
  790.   prttext("How?\r\n");
  791.   prttext("This font was converted\r\n");
  792.   prttext("from Windows. FntToLP4\r\n");
  793.   prttext("can convert almost any\r\n");
  794.   prttext("font into a LP4 font.");
  795.   formtext="Press a key.";
  796.   txtcrsr(320-(uword)txtwidth(formtext),340);
  797.   prttext(formtext);
  798.   bltmode(BM_SOLID);
  799.  
  800.   /* free menu font */
  801.   font(0); freefc(introfc); introfc=0;
  802.  
  803.   /* still showing page number 0... */
  804.   if (!getch()) getch();
  805.  
  806.   /* ...now show page number 1 */
  807.   waittof(); viewpage(1);
  808.  
  809.   /* load yet another pattern (while the user is still reading) */
  810.   filename="lp4demo\\rough.lp4";
  811.   font1bc=readbc(filename,1,&loaderr);
  812.   if (!font1bc) { error=DEMOERR_LOAD; goto fontcleanup; };
  813.  
  814.   /* load ye olde font */
  815.   filename="lp4demo\\oldefnt.lp4";
  816.   fontfc=readfc(filename,1,&loaderr);
  817.   if (!fontfc) { error=DEMOERR_LOAD; goto fontcleanup; };
  818.  
  819.   /* set olde font as active font */
  820.   font(fontfc->tgdfmdescr);
  821.  
  822.   /* still showing page number 1 */
  823.   if (!getch()) getch();
  824.  
  825.  
  826.   /* fade to black */
  827.   fade(210,0,fontbc->cmdescr->colors,allblack,fontbc->cmap);
  828.   waittof(); rgb6(0,255,allblack);
  829.  
  830.   /* free 1st pattern (strips) */
  831.   freebc(fontbc); fontbc=0;
  832.  
  833.   /* go from 320x400 phys. res. to 320x200 phys. res.
  834.    * 320x200 page mode will initially be set by screenmode()
  835.    */
  836.   waittof(); screenmode(SM_320x200);
  837.  
  838.   /* prepare page 1 */
  839.   drawpage(1);
  840.   bltbitmap(0,0,0,0,font1bc->tgdbmdescr->xsize,font1bc->tgdbmdescr->ysize,font1bc->tgdbmdescr);
  841.   pattern(0,0,font1bc->tgdbmdescr->xsize+1,font1bc->tgdbmdescr->ysize+1);
  842.   pfill(TRUE);
  843.   rectangle(0,200,319,399);
  844.   pfill(FALSE);
  845.  
  846.   bltmode(BM_TRANSPARENT|BM_COLREPLACE);
  847.   bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,4);
  848.   drawmode(DM_OR);
  849.   formtext="TGDLP4 Font Specifications";
  850.   textsize=(uword)txtwidth(formtext);
  851.   txtcrsr((320-textsize)>>1,212);
  852.   prttext(formtext);
  853.   rectangle((320-textsize)>>1,237,(320+textsize)>>1,240);
  854.   txtcrsr(0,250);
  855.   prttext("Char. size: 1x1 - 255x255 pixels.\r\n");
  856.   prttext("Font types: prop. & fixed width.\r\n");
  857.   prttext("Multicolor fonts ARE supported.\r\n");
  858.   prttext("All blit and draw modifiers also\r\n");
  859.   prttext("apply to fonts.\r\n");
  860.   prttext("Press a key for examples.");
  861.   drawmode(DM_SOLID); bltmode(BM_SOLID);
  862.  
  863.   /* prepare page 0 - the one to show first */
  864.   drawpage(0);
  865.   bltbitmap(0,0,0,0,font1bc->tgdbmdescr->xsize,font1bc->tgdbmdescr->ysize,font1bc->tgdbmdescr);
  866.   drawreg(0,200,319,199); clearreg();
  867.  
  868.   /* do some pattern tricks */
  869.   pattern(0,0,font1bc->tgdbmdescr->xsize+1,font1bc->tgdbmdescr->ysize+1);
  870.   pfill(TRUE);
  871.   drawpoly(3,triangle1); drawpoly(3,triangle2); drawpoly(3,triangle3); drawpoly(3,triangle4);
  872.   pfill(FALSE);
  873.  
  874.   fade(140,0,font1bc->cmdescr->colors,font1bc->cmap,allblack);
  875.  
  876.   framewait(35);
  877.  
  878.   pfill(TRUE);
  879.   for (a=0;a<=160;a+=2)
  880.   { waittof();
  881.     ellipse(160,300,a,(a>>1)+(a>>3));
  882.   };
  883.   pfill(FALSE);
  884.  
  885.   /* show already prepared screen */
  886.   waittof(); viewpage(1);
  887.  
  888.   /* load demo fonts while the user is busy reading text */
  889.   filename="lp4demo\\tiffafnt.lp4";
  890.   font1fc=readfc(filename,1,&loaderr);
  891.   if (!font1fc) { error=DEMOERR_LOAD; goto fontcleanup; };
  892.  
  893.   filename="lp4demo\\future.lp4";
  894.   font2fc=readfc(filename,1,&loaderr);
  895.   if (!font2fc) { error=DEMOERR_LOAD; goto fontcleanup; };
  896.  
  897.   /* get user input */
  898.   if (!getch()) getch();
  899.  
  900.   /* stenciled whiteness fade */
  901.   fade(140,1,2,(font1bc->cmap)+15,(font1bc->cmap)+3);
  902.   framewait(35);
  903.  
  904.   drawpage(1);
  905.   pen(PEN_F,7);
  906.   for (a=200;a<400;a+=1)
  907.   { waittof();
  908.     line(0,600-a,39,600-a);
  909.     line(40,a,79,a);
  910.     line(80,600-a,119,600-a);
  911.     line(120,a,159,a);
  912.     line(160,600-a,199,600-a);
  913.     line(200,a,239,a);
  914.     line(240,600-a,279,600-a);
  915.     line(280,a,319,a);
  916.   };
  917.  
  918.   /* set all colors that will be visible to white (except border color) */
  919.   waittof(); rgb6(16,0,allblack); ovscol(16);
  920.   waittof(); rgb6(0,15,allwhite);
  921.  
  922.   /* fill screen with the rough pattern for the last time */
  923.   viewmode(VM_1280x200);
  924.   bltbitmap(0,0,0,0,font1bc->tgdbmdescr->xsize,font1bc->tgdbmdescr->ysize,font1bc->tgdbmdescr);
  925.   pattern(0,0,font1bc->tgdbmdescr->xsize+1,font1bc->tgdbmdescr->ysize+1);
  926.   pfill(TRUE);
  927.   rectangle(320,0,959,199);
  928.   pfill(FALSE);
  929.  
  930.   /* free rough pattern */
  931.   freebc(font1bc); font1bc=0;
  932.  
  933.   /* prepare visible part of screen */
  934.   bltmode(BM_TRANSPARENT|BM_COLREPLACE);
  935.   bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,4);
  936.   txtcrsr(320,0);
  937.   prttext("And here come the examples...\r\n\n");
  938.   font(font1fc->tgdfmdescr);
  939.   prttext("This is a propor-\r\n");
  940.   prttext("tional width\r\n");
  941.   prttext("font.");
  942.   font(font2fc->tgdfmdescr);
  943.   txtcrsr(320,170);
  944.   prttext("THIS IS A FIXED WIDTH FONT.");
  945.   formtext="PRESS CURSOR RIGHT KEY";
  946.   txtcrsr(320+((320-(uword)txtwidth(formtext))>>1),192);
  947.   prttext(formtext);
  948.   bltmode(BM_SOLID);
  949.  
  950.   /* show screen */
  951.   viewreg(320,0);
  952.   fade(140,0,15,patt2col,allwhite);
  953.   ovscol(0);
  954.  
  955.   /* prepare invisible part of screen */
  956.   bltmode(BM_TRANSPARENT|BM_COLREPLACE);
  957.   font(font2fc->tgdfmdescr);
  958.   txtcrsr(640,0);
  959.   prttext("THIS TEXT IS LEFT ALIGNED.");
  960.   font(font1fc->tgdfmdescr);
  961.   formtext="centered";
  962.   txtcrsr(640+((320-(uword)txtwidth(formtext))>>1),24);
  963.   prttext(formtext);
  964.   font(fontfc->tgdfmdescr);
  965.   formtext="This text is right aligned.";
  966.   txtcrsr(640+(320-(uword)txtwidth(formtext)),64);
  967.   prttext(formtext);
  968.  
  969.   font(font2fc->tgdfmdescr);
  970.   formtext="REPLACED FOREGROUNDCOLOR\r\n";
  971.   txtcrsr(640,120);
  972.   pen(PEN_F,5);
  973.   prttext(formtext);
  974.   pen(PEN_F,6);
  975.   prttext(formtext);
  976.   prttext("\n");
  977.  
  978.   pen(PEN_F,4);
  979.   formtext="REPLACED BACKGROUNDCOLOR\r\n";
  980.   pen(PEN_B,7);
  981.   prttext(formtext);
  982.   bltmode(BM_COLREPLACE);
  983.   pen(PEN_B,0);
  984.   prttext(formtext);
  985.   prttext("\n");
  986.  
  987.   bltmode(BM_TRANSPARENT|BM_COLREPLACE); drawmode(DM_OR);
  988.   pen(PEN_B,0); pen(PEN_F,8);
  989.   prttext("REVERSE SHADOWS\r\n");
  990.   bltpen(PEN_B,1); bltpen(PEN_F,0); pen(PEN_B,1); pen(PEN_F,8);
  991.   prttext("INVERSE REVERSE SHADOWS???");
  992.  
  993.   bltpen(PEN_B,0); bltpen(PEN_F,1); pen(PEN_B,0); pen(PEN_F,12);
  994.   formtext="STOP THIS...PRESS CURSOR RIGHT KEY";
  995.   txtcrsr(640+((320-(uword)txtwidth(formtext))>>1),192);
  996.   prttext(formtext);
  997.   drawmode(DM_SOLID); bltmode(BM_SOLID);
  998.  
  999.   /* free all used fonts */
  1000.   freefc(fontfc); fontfc=0;
  1001.   freefc(font1fc); font1fc=0;
  1002.   freefc(font2fc); font2fc=0;
  1003.  
  1004.   /* the user is still watching the 1st screen */
  1005.   while (!crsrrightkey)
  1006.   { if (getch()) continue;
  1007.     if (getch()==CRSR_RIGHT_KEY) crsrrightkey=TRUE;
  1008.   };
  1009.  
  1010.   /* scroll invisible part of virtual screen into display area */
  1011.   for (a=320;a<=640;a+=1)
  1012.   { viewreg(a,0); };
  1013.  
  1014.   /* prepare a white screen area */
  1015.   pen(PEN_F,4); rectangle(960,0,1279,199);
  1016.  
  1017.   /* wait for user */
  1018.   crsrrightkey=FALSE;
  1019.   while (!crsrrightkey)
  1020.   { if (getch()) continue;
  1021.     if (getch()==CRSR_RIGHT_KEY) crsrrightkey=TRUE;
  1022.   };
  1023.  
  1024.   /* scroll into white area */
  1025.   for (a=640;a<=960;a+=1)
  1026.   { viewreg(a,0); };
  1027.  
  1028.   framewait(7);
  1029.   fade(70,0,0,allwhite,patt2col);
  1030.  
  1031. fontcleanup:
  1032.   if (error) { /* just in case a user defined font is still active */
  1033.            font(0);
  1034.  
  1035.            /* clean up everything */
  1036.            if (introfc) freefc(introfc);
  1037.            if (fontbc) freebc(fontbc);
  1038.            if (font1bc) freebc(font1bc);
  1039.            if (fontfc) freefc(fontfc);
  1040.            if (font1fc) freefc(font1fc);
  1041.            if (font2fc) freefc(font2fc);
  1042.          };
  1043.   return(error);
  1044. }
  1045.  
  1046. main()
  1047. { const char loaderr1[]="NO_FILE",loaderr2[]="BAD_FILE",loaderr3[]="NO_MEM",loaderr4[]="EOF";
  1048.   const char *lerrtxt[4];
  1049.   int pressedkey;
  1050.  
  1051.   const ubyte nxtgencolor1[]={  0,0,0,  63,63,63,  63,63,63,  63,63,63,  63,63,63 };
  1052.   const ubyte nxtgencolor2[]={  0,0,0,  63,63,63,   0,63,0,  63,0,0,   0,0,63 };
  1053.   ubyte topic=0;
  1054.   byte topicselected;
  1055.   word a;
  1056.   word talegon[]={ 36,194, 46,194, 56,148, 46,148 };
  1057.   bcdescr huge *introbc=0;
  1058.   scdescr huge *introsc=0;
  1059.   spriteinc far *introsprite=0;
  1060.   fcdescr huge *introfc=0;
  1061.  
  1062.   /* variable initializations: */
  1063.   /* possible load errors */
  1064.   lerrtxt[0]=loaderr1; lerrtxt[1]=loaderr2;
  1065.   lerrtxt[2]=loaderr3; lerrtxt[3]=loaderr4;
  1066.   /* standard fades */
  1067.   memset(allblack,0,768);
  1068.   memset(allwhite,63,768);
  1069.  
  1070.   randomize();
  1071.  
  1072.  
  1073.   /* initialize graphics driver */
  1074.   if (vgalp4()) { printf("?No VGA card or VGA card with less than 256KB installed\n Can't run demo!\n");
  1075.           return(DEMOERR_BADVGA);
  1076.         };
  1077.  
  1078.  
  1079.   /* for the nxtgen intro I want 320x400 phys. resolution... */
  1080.   waittof(); screenmode(SM_320x400);
  1081.   /* ...and 320x819 virtual resolution */
  1082.   viewmode(VM_320x800); pen(PEN_F,0); rectangle(0,0,319,399);
  1083.  
  1084.   /* load next generation bitmap */
  1085.   filename="lp4demo\\nxtgen.lp4";
  1086.   introbc=readbc(filename,1,&loaderr);
  1087.   if (!introbc) { error=DEMOERR_LOAD; goto cleanup; };
  1088.  
  1089.   /* load star sprite */
  1090.   filename="lp4demo\\star.sp4";
  1091.   introsc=readsc(filename,1,&loaderr);
  1092.   if (!introsc) { error=DEMOERR_LOAD; goto cleanup; };
  1093.   /* ready star sprite */
  1094.   introsprite=newsprite(0,0,0,0,introsc->tgdsmdescr);
  1095.   if (!introsprite) { error=DEMOERR_NOMEM; goto cleanup; };
  1096.  
  1097.   /* hide graphics generation by setting all used colors to black */
  1098.   waittof(); rgb6(0,4,allblack);
  1099.  
  1100.   /* blit next generation bitmap into VRAM */
  1101.   bltbitmap(54,140,0,0,introbc->tgdbmdescr->xsize,introbc->tgdbmdescr->ysize,introbc->tgdbmdescr);
  1102.  
  1103.   /* draw the talegons - each with a different color */
  1104.   for (a=2;a<5;a+=1)
  1105.   { pen(PEN_F,a);
  1106.     drawpoly(4,talegon);
  1107.     talegon[0]-=16; talegon[2]-=16; talegon[4]-=16; talegon[6]-=16;
  1108.   };
  1109.  
  1110.   /* add sprite to display list and init sprite position */
  1111.   addspr(0,0,400,introsprite);
  1112.   movespr(0,8,136);
  1113.  
  1114.   /* show everything (except sprite) */
  1115.   fade(210,0,4,nxtgencolor1,allblack);
  1116.   framewait(35);
  1117.   fade(70,0,4,nxtgencolor2,nxtgencolor1);
  1118.   framewait(140);
  1119.  
  1120.   /* do a little sprite animation */
  1121.   onspr(0);
  1122.   for (a=0;a<7;a+=1)
  1123.   { animspr(0,a);
  1124.     waittof(); refreshspr();
  1125.     framewait(6);
  1126.   };
  1127.  
  1128.   for (a=7;a>=0;a-=1)
  1129.   { animspr(0,a);
  1130.     waittof(); refreshspr();
  1131.     framewait(6);
  1132.   };
  1133.  
  1134.   /* free next generation bitmap - we don't need it anymore */
  1135.   freebc(introbc); introbc=0;
  1136.  
  1137.   /* free star sprite */
  1138.   offspr(0); refreshspr(); removespr(0);
  1139.   freesprite(introsprite); introsprite=0;
  1140.   freesc(introsc); introsc=0;
  1141.  
  1142.   /* fade into white */
  1143.   fade(140,0,4,allwhite,nxtgencolor2);
  1144.  
  1145.  
  1146. menureenter:
  1147.   /* set every color of the 256 colors to white */
  1148.   waittof(); rgb6(0,255,allwhite);
  1149.  
  1150.   /* set 320x400 phys. resolution, 320x819 virtual resolution */
  1151.   waittof(); screenmode(SM_320x400); viewmode(VM_320x800);
  1152.  
  1153.   /* load tale logo background */
  1154.   filename="lp4demo\\talebgnd.lp4";
  1155.   introbc=readbc(filename,1,&loaderr);
  1156.   if (!introbc) { error=DEMOERR_LOAD; goto cleanup; };
  1157.  
  1158.   /* blit tale logo into VRAM at virtual position (0,400) */
  1159.   bltbitmap(0,400,0,0,319,399,introbc->tgdbmdescr);
  1160.   /* we need to use a double buffer for the upcoming text F/X */
  1161.   vramcopy(0,0,0,400,320,400);
  1162.  
  1163.   /* oh whiteness - stay a while but don't stay forever! */
  1164.   framewait(70);
  1165.  
  1166.   /* display the lower part of the virtual screen -
  1167.    * just to be able to produce the quit effect
  1168.    */
  1169.   viewreg(0,400);
  1170.   fade(210,0,255,introbc->cmap,allwhite);
  1171.  
  1172.   /* load intro font */
  1173.   filename="lp4demo\\introfnt.lp4";
  1174.   introfc=readfc(filename,1,&loaderr);
  1175.   if (!introfc) { error=DEMOERR_LOAD; goto cleanup; };
  1176.  
  1177.   /* load selection border sprite */
  1178.   filename="lp4demo\\txtbordr.sp4";
  1179.   introsc=readsc(filename,1,&loaderr);
  1180.   if (!introsc) { error=DEMOERR_LOAD; goto cleanup; };
  1181.   /* ready selection border sprite */
  1182.   introsprite=newsprite(0,0,0,0,introsc->tgdsmdescr);
  1183.   if (!introsprite) { error=DEMOERR_NOMEM; goto cleanup; };
  1184.  
  1185.   /* set intro font as active font */
  1186.   font(introfc->tgdfmdescr);
  1187.   /* font shall be printed TRANSPARENTLY */
  1188.   bltmode(BM_TRANSPARENT); bltpen(PEN_B,0);
  1189.   /* prepare text pattern */
  1190.   txtcrsr(0,0);
  1191.   prttext("Use cursor keys to select:");
  1192.   txtcrsr(50,96);
  1193.   prttext("Graphic Primitives\r\nBitmaps\r\nFonts & Text\r\nQuit");
  1194.   /* be careful with blitmode: set it back to SOLID if you don't want to
  1195.    * wonder why the next blit is not working as it should and spend time on
  1196.    * debugging all day.
  1197.    */
  1198.   bltmode(BM_SOLID);
  1199.  
  1200.   /* prepare border sprite for display */
  1201.   addspr(0,0,0,introsprite);
  1202.   movespr(0,43,494+60*(uword)topic);
  1203.  
  1204.   /* set pattern */
  1205.   pattern(0,0,320,400);
  1206.   pfill(TRUE);
  1207.   /* pattern-in text */
  1208.   for (a=0;a<400;a+=2)
  1209.   { waittof();
  1210.     line(0,a+400,319,a+400);
  1211.     line(0,799-a,319,799-a);
  1212.   };
  1213.   /* disable pattern fill */
  1214.   pfill(FALSE);
  1215.  
  1216.   /* initially display border sprite */
  1217.   onspr(0);
  1218.   refreshspr();
  1219.  
  1220.   topicselected=FALSE; a=1;
  1221.   /* let the user select a menu item */
  1222.   while (!topicselected)
  1223.   { /* do some fancy color cycling while no user input to process */
  1224.     while (!kbhit())
  1225.     { framewait(6);
  1226.       rgb6(2+a,3-a,introsc->cmap+6);
  1227.       if (a) rgb6(2,a-1,introsc->cmap+6+(4-a)*3);
  1228.       a=(a+1)&3;
  1229.     };
  1230.  
  1231.     /* evaluate key codes */
  1232.     pressedkey=getch();
  1233.     if (!pressedkey) { pressedkey=getch();
  1234.                /* user command: [go to new topic] */
  1235.                if (pressedkey==CRSR_DOWN_KEY && topic<3) topic+=1;
  1236.                if (pressedkey==CRSR_UP_KEY && topic>0) topic-=1;
  1237.              }
  1238.     else { switch (tolower(pressedkey))
  1239.        { /* [execute topic] keycodes */
  1240.          case ESC_KEY: topic=3; topicselected=TRUE; break;
  1241.          case ENTER_KEY: topicselected=TRUE; break;
  1242.          case SPACE_KEY: topicselected=TRUE; break;
  1243.          /* direct selection of topics */
  1244.          case 'g': topic=0; break;
  1245.          case 'b': topic=1; break;
  1246.          case 'f': topic=2; break;
  1247.          case 'q': topic=3; break;
  1248.        };
  1249.      };
  1250.     /* tgdlp4xx.obj does only something if the sprite is *REALLY* moved */
  1251.     movespr(0,43,494+60*(uword)topic); refreshspr();
  1252.   };
  1253.  
  1254.   /* free tale logo bitmap - if selected topic is not quit or graph. prim. */
  1255.   if (topic!=3 && topic!=0) { freebc(introbc); introbc=0; };
  1256.   /* free font - if selected topic is not fonts and text */
  1257.   if (topic!=2) { font(0); freefc(introfc); introfc=0; };
  1258.   /* remove selection border */
  1259.   offspr(0); refreshspr(); removespr(0);
  1260.   freesprite(introsprite); introsprite=0;
  1261.   freesc(introsc); introsc=0;
  1262.  
  1263.   /* call program parts according to topic selection */
  1264.   switch (topic)
  1265.   { case 0: error=primdemo(introbc);
  1266.         if (!error) goto menureenter;
  1267.         else goto cleanup;
  1268.     case 1: error=bitmapdemo();
  1269.         if (!error) goto menureenter;
  1270.         else goto cleanup;
  1271.     case 2: error=fontdemo(introfc);
  1272.         if (!error) goto menureenter;
  1273.         else goto cleanup;
  1274.   };
  1275.  
  1276.  
  1277.   /* QUIT: */
  1278.   /* blit tale logo into double buffer */
  1279.   bltbitmap(0,0,0,0,319,399,introbc->tgdbmdescr);
  1280.  
  1281.   /* pattern-in tale logo */
  1282.   pattern(0,0,320,400);
  1283.   pfill(TRUE);
  1284.   for (a=0;a<200;a+=1)
  1285.   { waittof();
  1286.     line(0,a+400,319,a+400);
  1287.     line(0,799-a,319,799-a);
  1288.   };
  1289.   pfill(FALSE);
  1290.  
  1291.   /* clear upper part of the virtual screen... */
  1292.   pen(PEN_F,0);
  1293.   rectangle(0,0,319,399);
  1294.   /* ...and scroll up */
  1295.   for (a=399;a>=0;a-=1)
  1296.   { viewreg(0,a); };
  1297.  
  1298.   /* free tale logo bitmap */
  1299.   freebc(introbc); introbc=0;
  1300.  
  1301. cleanup:
  1302.   /* return to textmode */
  1303.   co80();
  1304.  
  1305.   if (error) { /* clean up memory */
  1306.            if (introbc) freebc(introbc);
  1307.            if (introsprite) freesprite(introsprite);
  1308.            if (introsc) freesc(introsc);
  1309.            if (introfc) freefc(introfc);
  1310.  
  1311.            /* which error did occur? */
  1312.            switch (error)
  1313.            { case DEMOERR_LOAD: printf("?Can't load file: %s [error code: %s]\nAborting.\n",filename,lerrtxt[loaderr-1]);
  1314.                     break;
  1315.          case DEMOERR_NOMEM: printf("?Out of memory\n");
  1316.                      break;
  1317.            };
  1318.          }
  1319.   else printf("Now it's your turn...\n");
  1320.  
  1321.   /* return error code to DOS */
  1322.   return(error);
  1323. }